package host.skiree.nettydemo.nio.c3;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author gcl
 * @date 2022/9/6 10:02
 */
@Slf4j
@SpringBootTest
public class NettyDemo {

    /**
     * 用来测试
     */
    @Test
    void FileChannelTransferTo() {
        try (
                FileChannel from = new FileInputStream("data.txt").getChannel();
                FileChannel to = new FileOutputStream("to.txt").getChannel();
        ) {
            // 效率高, 底层会使用操作系统的零拷贝进行优化, 最大传输 2G 数据
            from.transferTo(0, from.size(), to);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    /**
     * 用来测试
     */
    @Test
    void FileChannelTransferToPro() {
        long start = System.nanoTime();
        try (
                FileChannel from = new FileInputStream("data.txt").getChannel();
                FileChannel to = new FileOutputStream("to.txt").getChannel();
        ) {
            // 效率高, 底层会使用操作系统的零拷贝进行优化, 优化最大传输 2G 数据
            long size = from.size();
            for ( long left = size ; left > 0 ; ){
                left -= from.transferTo((size - left), left, to);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        long end = System.nanoTime();
        System.out.println("transferTo 用时：" + (end - start) / 1000_000.0);
    }

    /**
     * 用来测试
     */
    @Test
    void FilesWalkFileTreeTest() throws IOException {
        AtomicInteger dirCount = new AtomicInteger();
        AtomicInteger fileCount = new AtomicInteger();
        Files.walkFileTree(Paths.get("C:\\Workspace\\netty-demo"), new SimpleFileVisitor<Path>(){
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                System.out.println("====>" + dir);
                dirCount.incrementAndGet();
                return super.preVisitDirectory(dir, attrs);
            }

            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                fileCount.incrementAndGet();
                return super.visitFile(file, attrs);
            }
        });
        System.out.println( "dir count :" + dirCount );
        System.out.println( "file count :" + fileCount );
    }

    /**
     * 用来测试
     */
    @Test
    void FilesWalkFileTreeTxt() throws IOException {
        AtomicInteger fileCount = new AtomicInteger();
        Files.walkFileTree(Paths.get("C:\\Workspace\\netty-demo"), new SimpleFileVisitor<Path>(){
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                return super.preVisitDirectory(dir, attrs);
            }

            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                if ( file.toString().endsWith(".txt") ){
                    fileCount.incrementAndGet();
                }
                return super.visitFile(file, attrs);
            }
        });
        System.out.println( "file count :" + fileCount );
    }

    /**
     * 用来测试
     */
    @Test
    void FilesWalkFileTreeDeleteFilePaths() throws IOException {
        Files.walkFileTree(Paths.get("C:\\Map"), new SimpleFileVisitor<Path>(){
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                // 删除文件
                Files.delete(file);
                return super.visitFile(file, attrs);
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                // 删除文件夹
                Files.delete(dir);
                return super.postVisitDirectory(dir, exc);
            }
        });
    }

    /**
     * 用来测试
     */
    @Test
    void FilesWalkCopy() throws IOException {
        String source = "C:\\Users\\anorak\\Desktop\\Map";
        String target = "C:\\Map";
        Files.walk(Paths.get(source)).forEach(path -> {
            try{
                String targetName = path.toString().replace(source, target);
                // 是目录
                if ( Files.isDirectory(path) ){
                    Files.createDirectory(Paths.get(targetName));
                }
                // 是文件
                else if ( Files.isRegularFile(path) ) {
                    Files.copy(path, Paths.get(targetName));
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        });
    }

}
